<?php
/**
 * Note:     [Description]
 * Author:   longhui.huang <1592328848@qq.com>
 * DateTime: 2024/1/24 12:33
 */
declare(strict_types=1);

namespace App\HttpController\Admin;

use App\Bean\OnlineUserBean;
use App\Cache\UserCache;
use App\HttpController\ApiBase;
use App\Model\UserModel;
use App\Service\Auth\OnlineUserService;
use App\Service\Auth\TokenService;
use App\Service\UserService;
use App\Utility\Log\Log;
use EasySwoole\Http\Message\Status;
use EasySwoole\Jwt\Exception;

class AdminBase extends ApiBase
{
    /** @var UserModel|null $user */
    protected $user;

    /** @var OnlineUserBean|null */
    protected $onlineUserBean;

    protected function onRequest(?string $action): ?bool
    {
        $isOk = parent::onRequest($action);
        if (!$isOk) {
            return $isOk;
        }

        $whiteUri       = config('whiteUri');
        $noNeedLoginUri = $whiteUri['no_need_login'];
        $currentUri     = $this->_request->server('request_uri');
        if (!in_array($currentUri, $noNeedLoginUri)) {
            // 需要登录 判断登录

            // check token
            /** @var TokenService $tokenService */
            $tokenService = app(TokenService::class);
            $token        = $tokenService->resolveToken($this->_request);

            if (!$token) {
                return json(['message' => 'fail'], Status::CODE_UNAUTHORIZED);
            }

            // 对于 Token 为空的不需要去查 Redis
            $cleanUserCache = false;
            /** @var OnlineUserService $onlineUserService */
            $onlineUserService = app(OnlineUserService::class);
            $onlineUserBean    = null;
            $username          = '';

            try {
                $jwtObject      = $tokenService->parseToken($token);
                $jwtData        = $jwtObject->getData() ?: [];
                $username       = $jwtData['username'] ?? '';
                $loginKey       = $tokenService->loginKey($jwtObject->getSub(), $token);
                $onlineUserBean = $onlineUserService->getOne($loginKey);
            } catch (Exception $e) {
                Log::error($e->getMessage());
                $cleanUserCache = true;
            } finally {
                if ($cleanUserCache || is_null($onlineUserBean)) {
                    if ($username) {
                        /** @var UserCache $userCache */
                        $userCache = app(UserCache::class);
                        $userCache->cleanUserCache($username);
                    }
                }
            }

            if (!$onlineUserBean) {
                return json(['message' => 'fail'], Status::CODE_UNAUTHORIZED);
            }

            $this->onlineUserBean = $onlineUserBean;
            // Token 续期
            $tokenService->checkRenewal($token);
            /** @var UserService $userService */
            $userService = app(UserService::class);
            $this->user  = $userService->findByUsername($onlineUserBean->getUsername());
        }

        $noNeedRightUri = $whiteUri['no_need_right'];
        if (!in_array($currentUri, $noNeedRightUri)) {
            // 需要校验权限
            // todo::
        }

        return true;
    }
}
